import 'package:fluwx/fluwx.dart';
import 'package:get/get.dart';
import 'package:sainbainu/common/utils/custom_exception.dart';
import 'package:sainbainu/common/values/settings.dart';

typedef AuthCodeSuccess = void Function(String? code);
typedef AuthCodeFail = void Function(WeChatAuthResponse res);

class WechatService extends GetxService {
  static WechatService get to => Get.find();

  late Fluwx _fluwx;

  /// 微信是否已安装
  Future<bool> get isWeChatInstalled => _fluwx.isWeChatInstalled;

  /// 获取 code 成功回调
  AuthCodeSuccess? _authCodeSuccess;

  /// 获取 code 失败回调
  AuthCodeFail? _authCodeFail;

  @override
  void onInit() {
    super.onInit();
    _register();
  }

  @override
  void onClose() {
    super.onClose();
    _fluwx.removeSubscriber(_listenerResponse);
  }

  /// 注册 SDK
  _register() {
    _fluwx = Fluwx();
    _fluwx.registerApi(
      appId: AppSettings.wechatAppId,
      universalLink: AppSettings.universalLink,
    );
    _fluwx.addSubscriber(_listenerResponse);
  }

  /// 监听回调
  _listenerResponse(WeChatResponse response) {
    if (response is WeChatAuthResponse) {
      if (response.errCode == 0) {
        // 获取 code 成功
        if (_authCodeSuccess != null) {
          _authCodeSuccess!(response.code);
          _authCodeSuccess = null;
        }
      } else {
        // 获取 code 失败
        if (_authCodeFail != null) {
          _authCodeFail!(response);
          _authCodeFail = null;
        }
      }
    } else if (response is WeChatShareResponse) {
      if (response.errCode == 0) {
        // 微信无法区分分享成功或失败了 都返回 0
      }
    }
  }

  /// 授权获取 code
  Future<bool> authCode(AuthCodeSuccess success, AuthCodeFail? fail) async {
    _authCodeSuccess = success;
    _authCodeFail = fail;
    return await _fluwx.authBy(
      which: NormalAuth(
        scope: 'snsapi_userinfo',
        state: 'sainbainu_wechat_sdk',
      ),
    );
  }

  /// 分享文字
  ///
  /// [text] 分享内容
  /// [scene] 分享场景
  /// [mediaTagName]
  /// [messageAction]
  /// [messageExt] 额外信息
  /// [msgSignature] 消息签名
  /// [description] 描述内容
  /// [title] 消息标题
  Future<bool> shareText(
    String text, {
    WeChatScene scene = WeChatScene.session,
    String? mediaTagName,
    String? messageAction,
    String? messageExt,
    String? msgSignature,
    String? description,
    String? title,
  }) async {
    return await _fluwx.share(WeChatShareTextModel(
      text,
      scene: scene,
      mediaTagName: mediaTagName,
      messageAction: messageAction,
      messageExt: messageExt,
      msgSignature: msgSignature,
      description: description,
      title: title,
    ));
  }

  /// 分享图片
  ///
  /// [source] 分享图
  /// [scene] 分享场景
  /// [thumbnail] 缩略图
  /// [mediaTagName]
  /// [messageAction]
  /// [messageExt] 额外信息
  /// [msgSignature] 消息签名
  /// [description] 描述内容
  /// [title] 消息标题
  /// [compressThumbnail] 是否压缩图片
  Future<bool> shareImage(
    WeChatImage source, {
    WeChatScene scene = WeChatScene.session,
    WeChatImage? thumbnail,
    String? mediaTagName,
    String? messageAction,
    String? messageExt,
    String? msgSignature,
    String? description,
    String? title,
    bool compressThumbnail = true,
  }) async {
    return await _fluwx.share(WeChatShareImageModel(
      source,
      scene: scene,
      thumbnail: thumbnail,
      mediaTagName: mediaTagName,
      messageAction: messageAction,
      messageExt: messageExt,
      msgSignature: msgSignature,
      description: description,
      title: title,
      compressThumbnail: compressThumbnail,
    ));
  }

  /// 分享音频
  ///
  /// [musicUrl] 音频网页的URL地址
  /// [musicLowBandUrl] 供低带宽的环境下使用的音频网页的URL地址
  /// [musicDataUrl] 音频数据的URL地址
  /// [musicLowBandDataUrl] 供低带宽的环境下使用的音频数据的URL地址
  /// [scene] 分享场景
  /// [thumbnail] 缩略图
  /// [mediaTagName]
  /// [messageAction]
  /// [messageExt] 额外信息
  /// [msgSignature] 消息签名
  /// [description] 描述内容
  /// [title] 消息标题
  /// [compressThumbnail] 是否压缩图片
  Future<bool> shareMusic({
    String? musicUrl,
    String? musicLowBandUrl,
    String? musicDataUrl,
    String? musicLowBandDataUrl,
    WeChatScene scene = WeChatScene.session,
    WeChatImage? thumbnail,
    String? mediaTagName,
    String? messageAction,
    String? messageExt,
    String? msgSignature,
    String? description,
    String? title,
    bool compressThumbnail = true,
  }) async {
    return await _fluwx.share(WeChatShareMusicModel(
      musicUrl: musicUrl,
      musicLowBandUrl: musicLowBandUrl,
      musicDataUrl: musicDataUrl,
      musicLowBandDataUrl: musicLowBandDataUrl,
      scene: scene,
      thumbnail: thumbnail,
      mediaTagName: mediaTagName,
      messageAction: messageAction,
      messageExt: messageExt,
      msgSignature: msgSignature,
      description: description,
      title: title,
      compressThumbnail: compressThumbnail,
    ));
  }

  /// 分享视频
  ///
  /// [videoUrl] 分享视频地址 videoUrl和videoLowBandUrl不能同时为空
  /// [videoLowBandUrl] 供低带宽的环境下使用的视频链接
  /// [scene] 分享场景
  /// [thumbnail] 缩略图
  /// [mediaTagName]
  /// [messageAction]
  /// [messageExt] 额外信息
  /// [msgSignature] 消息签名
  /// [description] 描述内容
  /// [title] 消息标题
  /// [compressThumbnail] 是否压缩图片
  Future<bool> shareVideo({
    String? videoUrl,
    String? videoLowBandUrl,
    WeChatScene scene = WeChatScene.session,
    WeChatImage? thumbnail,
    String? mediaTagName,
    String? messageAction,
    String? messageExt,
    String? msgSignature,
    String? description,
    String? title,
    bool compressThumbnail = true,
  }) async {
    return await _fluwx.share(WeChatShareVideoModel(
      videoUrl: videoUrl,
      videoLowBandUrl: videoLowBandUrl,
      scene: scene,
      thumbnail: thumbnail,
      mediaTagName: mediaTagName,
      messageAction: messageAction,
      messageExt: messageExt,
      msgSignature: msgSignature,
      description: description,
      title: title,
      compressThumbnail: compressThumbnail,
    ));
  }

  /// 分享文件
  ///
  /// [source] 分享文件
  /// [scene] 分享场景
  /// [thumbnail] 缩略图
  /// [mediaTagName]
  /// [messageAction]
  /// [messageExt] 额外信息
  /// [msgSignature] 消息签名
  /// [description] 描述内容
  /// [title] 消息标题
  /// [compressThumbnail] 是否压缩图片
  Future<bool> shareFile(
    WeChatFile source, {
    WeChatScene scene = WeChatScene.session,
    WeChatImage? thumbnail,
    String? mediaTagName,
    String? messageAction,
    String? messageExt,
    String? msgSignature,
    String description = '',
    String title = '',
    bool compressThumbnail = true,
  }) async {
    return await _fluwx.share(WeChatShareFileModel(
      source,
      scene: scene,
      thumbnail: thumbnail,
      mediaTagName: mediaTagName,
      messageAction: messageAction,
      messageExt: messageExt,
      msgSignature: msgSignature,
      description: description,
      title: title,
      compressThumbnail: compressThumbnail,
    ));
  }

  /// 分享网页
  ///
  /// [webPage] 网页地址
  /// [scene] 分享场景
  /// [thumbnail] 缩略图
  /// [mediaTagName]
  /// [messageAction]
  /// [messageExt] 额外信息
  /// [msgSignature] 消息签名
  /// [description] 描述内容
  /// [title] 消息标题
  /// [compressThumbnail] 是否压缩图片
  Future<bool> shareWeb(
    String webPage, {
    WeChatScene scene = WeChatScene.session,
    WeChatImage? thumbnail,
    String? mediaTagName,
    String? messageAction,
    String? messageExt,
    String? msgSignature,
    String? description,
    String title = '',
    bool compressThumbnail = true,
  }) async {
    return await _fluwx.share(WeChatShareWebPageModel(
      webPage,
      scene: scene,
      thumbnail: thumbnail,
      mediaTagName: mediaTagName,
      messageAction: messageAction,
      messageExt: messageExt,
      msgSignature: msgSignature,
      description: description,
      title: title,
      compressThumbnail: compressThumbnail,
    ));
  }

  /// 分享小程序
  ///
  /// [webPageUrl] 兼容低版本的网页链接
  /// [userName] 小程序的userName（设置-基本设置-账号信息-原始ID）
  /// [thumbnail] 缩略图
  /// [miniProgramType] 打开的版本
  /// [path] 小程序的页面路径
  /// [withShareTicket] 是否使用带shareTicket的分享
  /// [hdImagePath] 小程序新版本的预览图 大小不超过128KB 长宽比5:4
  /// [mediaTagName]
  /// [messageAction]
  /// [messageExt] 额外信息
  /// [msgSignature] 消息签名
  /// [description] 描述内容
  /// [title] 消息标题
  /// [compressThumbnail] 是否压缩图片
  Future<bool> shareMp({
    required String webPageUrl,
    required String userName,
    required WeChatImage thumbnail,
    WXMiniProgramType miniProgramType = WXMiniProgramType.release,
    String path = '/',
    bool withShareTicket = false,
    WeChatImage? hdImagePath,
    String? mediaTagName,
    String? messageAction,
    String? messageExt,
    String? msgSignature,
    String? description,
    String? title,
    bool compressThumbnail = true,
  }) async {
    return await _fluwx.share(WeChatShareMiniProgramModel(
      webPageUrl: webPageUrl,
      userName: userName,
      thumbnail: thumbnail,
      miniProgramType: miniProgramType,
      path: path,
      withShareTicket: withShareTicket,
      hdImagePath: hdImagePath,
      mediaTagName: mediaTagName,
      messageAction: messageAction,
      messageExt: messageExt,
      msgSignature: msgSignature,
      description: description,
      title: title,
      compressThumbnail: compressThumbnail,
    ));
  }
}
